package com.unitd.modules.gen.controller;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.unitd.comm.web.BaseController;
import com.unitd.frame.comm.tree.Ztree;
import com.unitd.frame.comm.utils.BeanUtils;
import com.unitd.frame.comm.utils.ListUtils;
import com.unitd.frame.comm.utils.StringUtils;
import com.unitd.frame.springweb.controller.result.AjaxResult;
import com.unitd.frame.sso.annotation.Action;
import com.unitd.frame.sso.annotation.Permission;
import com.unitd.modules.gen.entity.GenTable;
import com.unitd.modules.gen.service.IGenTableService;
import com.unitd.modules.gen.util.GenUtils;
import com.unitd.modules.sys.entity.SysDict;
import com.unitd.modules.sys.service.ISysDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @desc 业务表Controller
 * @filename GenTableController.java
 * @copyright www.unitd.com
 * @author Hudan
 * @version 1.0
 * @date 2017/4/27
 */
@Controller
@RequestMapping("/gen/genTable")
public class GenTableController extends BaseController {

	@Autowired
	private IGenTableService genTableService;
	@Autowired
	private ISysDictService sysDictService;

	/**
	 * @desc 转到信息列表页
	 * @return 列表页地址
	 */
	@Permission("gen:genTable:list")
	@RequestMapping("/list")
	public String list() {
		return "/modules/gen/table/list";
	}

	/**
	 * @desc 获取信息列表json数据,方便列表页通过ajax获取并展示
	 * @return json数据
	 */
	@Permission("gen:genTable:list")
	@RequestMapping("/listJson")
	@ResponseBody
	public String listJson(GenTable genTable) {
		// 获取分页数据信息
		Map<String, Integer> pageMap = getPageMap();

		// 查询列表数据
		PageInfo<GenTable> pageData = genTableService.getPageData(pageMap.get("pageNo"), pageMap.get("pageSize"), genTable);
		return jsonPage(pageData);
	}

	/**
	 * @desc 转到新增生成方案表机构对象信息
	 * @param model springMVC的数据模型
	 * @return 新增页
	 */
	@Permission("gen:genTable:edit")
	@RequestMapping(value = "/toAdd")
	public String toAdd(Model model) {
		// 获取物理表列表
		List<GenTable> tableList = genTableService.findTableListFormDb(new GenTable());

		model.addAttribute("tableList", tableList);
		return "/modules/gen/table/add";
	}

	/**
	 * @desc 根据主键ID获取详情信息,并将获取的信息在详情页展示转到信息列表页
	 * @param genTable 业务表对象信息
	 * @param param 前端请求参数
	 * @return 详情页地址及数据
	 */
	@Permission("gen:genTable:edit")
	@RequestMapping(value = "/doAdd")
	@ResponseBody
	public AjaxResult doAdd(GenTable genTable, @RequestParam Map<String, Object> param) {

		if (!genTableService.checkTableName(genTable.getTableName())) {
			genTable.setTableName("");
			return new AjaxResult(false, "下一步失败! 表[" + param.get("tableName") + "]已经添加,请重新选择需要添加的表!");
		} else {
			return new AjaxResult(true);
		}
	}

	/**
	 * @desc 根据主键ID获取详情信息, 并将获取的信息在详情页展示转到信息列表页
	 * @return 详情页地址及数据
	 */
	@Permission("sys:sysMenu:view")
	@RequestMapping("/toView/{id}")
	public String toView(Model model, @PathVariable("id") String tableId) {
		// 获取数据对象
		getDataById(model, new GenTable(tableId), null);

		// 转到对应前端页面
		model.addAttribute("action", "doView");
		return "/modules/gen/table/edit";
	}

	/**
	 * @desc 根据主键ID获取详情信息,并将获取的信息在详情页展示转到信息列表页
	 * @param model springMVC的数据模型
	 * @param genTable 业务表对象信息
	 * @param param 前端请求参数
	 * @return 详情页地址及数据
	 */
	@Permission("gen:genTable:edit")
	@RequestMapping(value = "/toEdit")
	public String toEdit(Model model, GenTable genTable, @RequestParam Map<String, Object> param) {
		// 获取数据对象
		getDataById(model, genTable, (String) param.get("operFlag"));

		return "/modules/gen/table/edit";
	}

	@Permission("gen:genTable:edit")
	@RequestMapping(value = "/doEdit", method = RequestMethod.POST)
	@ResponseBody
	public AjaxResult doEdit(Model model, GenTable genTable) {
		// 调用Hibernate-validate进行数据校验
		String validatMsg = beanValidator(model, genTable);
		if(!StringUtils.isNull(validatMsg)) {
			return new AjaxResult(false, "处理数据失败![" +validatMsg+"]");
		}

		// 验证表是否已经存在
		if(StringUtils.isZero(genTable.getId()) && !genTableService.checkTableName(genTable.getTableName())) {
			genTable.setTableName("");
			return new AjaxResult(false, "保存失败![" + genTable.getTableName() + " 表已经存在]");
		}
		// 保存数据
		genTableService.doEdit(genTable, getSSOToken().getUid());

		// 返回前台结果
		return new AjaxResult(true);
	}

	/**
	 * @desc 逻辑删除前端指定的数据
	 * @param genTable 业务表对象
	 * @return 删除解雇哦
	 */
	@Permission("gen:genTable:delete")
	@RequestMapping(value = "doDelete")
	@ResponseBody
	public AjaxResult doDelete(GenTable genTable) {
		// 逻辑删除
		genTableService.deleteByDelFlag(genTable);
		return new AjaxResult(true);
	}

	/**
	 * @desc 转到选择系统中数据库表类型树的页面
	 * @param model SpringMVC的数据模型对象
	 * @param param 请求参数
	 * @return 表结构选择页
	 */
	@Permission(action = Action.Skip)
	@RequestMapping("/toTableCategory")
	public String tocategoryValue(Model model, @RequestParam Map<String, Object> param) {
		// 获取系统表类型信息
		List<SysDict> categoryList = sysDictService.findListBy(new SysDict("tableCategory"));

		model.addAttribute("currentId", param.get("currentId"));
		model.addAttribute("categorys", JSON.toJSONString(categoryList));

		return "/modules/gen/table/tableCategoryTree";
	}

	/**
	 * @desc 转到选择已配置的数据表信息树的页面
	 * @param model SpringMVC的数据模型对象
	 * @param param 请求参数
	 * @return 表结构树
	 */
	@Permission(action = Action.Skip)
	@RequestMapping("/toTableTree")
	public String toTableTree(Model model, @RequestParam Map<String, Object> param) {

		// 获取物理表列表
		List<GenTable> tables = genTableService.listAll();

		/* 将从数据库中读取的已配置的需要生成代码的表对象信息进行遍历并组装生产对应的ztree集合对象 */
		List<Ztree> rootList = Lists.newArrayList(); 					// 最外层的数据集合对象

		if(!ListUtils.isNull(tables)) {
			List<Ztree> children; 										// 子节点集合对象
			Ztree parent; 												// 父级节点对象
			Ztree vo; 													// 子节点对象

			Map<String, Ztree> tempMap = Maps.newConcurrentMap();
			for (GenTable table : tables) {
				vo = new Ztree();
				vo.setId(table.getTableName()); 						// 表名
				vo.setName(table.getComments()); 						// 表说明
				vo.setpId(table.getCategoryValue()); 					// 表所属类型

				parent = tempMap.get(vo.getpId());
				if(BeanUtils.isNull(parent)) {
					parent = tempMap.get(table.getCategoryValue());
				}

				if (!BeanUtils.isNull(parent)) {
					children = parent.getChildren();

					if(ListUtils.isNull(children)) {
						children = new ArrayList<>();
						parent.setChildren(children);
					}
					children.add(vo);
					tempMap.put(vo.getId(), vo);
				} else {
					// 父节点,其实就是表所属的表类型
					parent = new Ztree();
					parent.setId(table.getCategoryValue()); 					// 表的值
					parent.setName(table.getCategoryName()); 					// 表的类型说明

					rootList.add(parent);
					tempMap.put(parent.getId(), parent);

					children = parent.getChildren();
					if(ListUtils.isNull(children)) {
						children = new ArrayList<>();
						parent.setChildren(children);
					}
					children.add(vo);
					tempMap.put(vo.getId(), vo);
				}
			}
		}
		// 将组装后的树结构的表对象信息转换成json串
		model.addAttribute("genTableNames", param.get("genTableNames"));
		model.addAttribute("tables", JSON.toJSONString(rootList));

		return "/modules/gen/table/tableTree";
	}


	/**
	 * @desc 根据生成业务表ID获取对应的需要生成的业务表详情,方便前端使用
	 * @param model springMVC的前端数据模型对象
	 * @param genTable 生成业务表主键ID
	 */
	private void getDataById(Model model, GenTable genTable, String operFlag) {
		// 获取物理表字段
		if(!StringUtils.isNull(operFlag) && "add".equals(operFlag)){
			genTable = genTableService.getTableFormDb(genTable);
			genTable.setCreateFo("0");
			genTable.setCreateAr("0");
		} else{
			genTable = genTableService.selectByPrimaryKey(genTable.getId());
		}

		// 获取物理表列表
		List<GenTable> tableList = genTableService.findTableListFormDb(new GenTable());

		model.addAttribute("tableList", tableList);
		model.addAttribute("genTable", genTable);
		model.addAttribute("config", GenUtils.getConfig());
	}
}